<?php

namespace App\Http\Controllers\Member;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Member\DealRecord;
use App\Models\Member\Order;
use App\Models\Member\User;
use App\Common\WechatHandler;
use Auth, Log;
use App\Tools\src\YopConfig;
use App\Tools\src\YopRequest;
use App\Tools\src\YopRsaClient;
use App\Tools\src\Util\YopSignUtils;
use Config;
use App\Models\Member\PayConfig;

class PayController extends Controller
{
    public function initOrder(Request $request)
    {
        $money = $request['money'] * 100;
        if($money < 100) {
            return $this->errorClient(['info' => '充值金额不能小于1元']);
        }
        $user = Auth::user()->toArray();
        $orderId =  "WECHAT_MB".date('Ymd').substr(time(), -4).mt_rand(1000,9999).$user["id"];
        $dealRecord = new DealRecord;
        if(empty($request['payType'])){
            $deal = $dealRecord->invest($user, $money, "微信充值", $orderId, 1);
        }else{
            $deal = $dealRecord->invest($user, $money, "微信支付会员订单", $orderId, 41, $request['id']);
        }

        $data = [];
        $data['openId'] = $user['open_id'];
        $data['storeId'] = $user['store_id'];
        $data['body'] = '微信充值';
        $data['notifyUrl'] = env("APP_URL").'/pay/callback';
        $data['tradeType'] = "JSAPI";
	    $data['url'] = $request['url'];
        $data['payOrderNum'] = $orderId;
        $data['totalFee'] = $money;
        
        $result = WechatHandler::makeWxOrder($data);
        return $this->successClient($result);
    }


    public function wxCallback(Request $request) {
        $xml = file_get_contents('php://input');
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
         
        
        if($data['return_code'] == 'SUCCESS'){
            $orderId = $data['out_trade_no'];
            $money = $data['total_fee'];
            Log::info('充值成功，订单ID为'.$orderId);
 
            $dealRecord = new DealRecord;
            $dealInfo = $dealRecord->where("pay_orderid",$orderId)->first();
             if($dealInfo->deal_type == 41){
                 Log::info('微信直接支付订单-订单ID:'.$dealInfo->deal_item_id);
                 $order = new Order;
                 $order->checkMemPay(2,$dealInfo->deal_item_id,$dealInfo->pay_orderid);
             }else{
                 $userId = $dealInfo->user_id;
 
                 $userModel = new User;
                 $user = $userModel->where("id",$userId)->first();
         
                 $deal = $dealRecord->investSuccess($dealInfo->id, $user->open_id, $dealInfo->amount);
             }
            echo '<xml>
                <return_code><![CDATA[SUCCESS]]></return_code>
                <return_msg><![CDATA[OK]]></return_msg>
                </xml>';
            exit();
        }
   }

    //易宝支付  聚合支付
    //微信支付
    public function ybPrePay(Request $request){
        $price = $request['money'];//单位:元
        if($price < 1) {
            return $this->errorClient(['info' => '充值金额不能小于1元']);
        }
        $url = $request['url'];

        $yopConfig = Config::get("const.yop_config");
        $user = Auth::user()->toArray();
        $pay_config = new PayConfig;
        $payConfig = $pay_config->where("store_id",$user["store_id"])->first();

        $orderId =  "WECHAT_MB_YOP_".date('Ymd').substr(time(), -4).mt_rand(1000,9999).$user["id"];
        /*商户私钥*/
        $private_key = $yopConfig["private_key"];
        $appKey = $yopConfig["appKey"];
        $parentMerchantNo = $yopConfig["parentMerchantNo"];
        $merchantNo = $payConfig["yop_merchantno"];
        $notifyUrl = env("APP_URL").'/pay/yopwxcallback';
        $memo = '易宝充值';
        $goodsName = '微信充值';
        $payWay = "WECHAT_OFFIACCOUNT";
        $channel = "WECHAT";
        $scene = "OFFLINE";
        $appId = $payConfig["app_id"];
        $userId = $user["open_id"];

        $dealRecord = new DealRecord;
        if(empty($request->payType)){
            $deal = $dealRecord->invest($user, $price*100, "微信充值", $orderId, 1);
        }else{
            $deal = $dealRecord->invest($user, $price*100, "微信支付会员订单", $orderId, 41, $request->id);
            $memo = '微信支付';
            $goodsName = '微信支付会员订单';
        }

        $request = new YopRequest($appKey, $private_key);
        
        //加入请求参数
        $request->addParam("parentMerchantNo", $parentMerchantNo);//发起方商户编号
        $request->addParam("merchantNo", $merchantNo);//商户编号
        $request->addParam("orderId", $orderId);//支付授权目录列表
        $request->addParam("orderAmount", $price);//支付授权目录列表
        $request->addParam("notifyUrl", $notifyUrl);//业务上是必须参数，支付成功服务器回调地址：支付成功通知、超时通知、失败通知。
        $request->addParam("redirectUrl", '');//页面回调地址。如使用易宝收银台需要上送前端页面回调地址
        $request->addParam("memo", $memo);//自定义对账备注 非必填
        $request->addParam("goodsName", $goodsName);//商品名称  必填
        $request->addParam("fundProcessType", 'REAL_TIME');//分账订单标记   非必填
        $request->addParam("payWay", $payWay);//支付方式
        $request->addParam("channel", $channel);//渠道类型
        $request->addParam("scene", $scene);//场景
        $request->addParam("appId", $appId);//微信公众号ID
        $request->addParam("userId", $userId);//用户ID用户标识，微信公众号/微信小程序为用户的openId，支付宝生活号/支付宝小程序/银联 JS 支付为用户的userId  非必填
        $request->addParam("userIp", $_SERVER['REMOTE_ADDR']);//用户真实IP地址
        
        //提交Post请求
        $response = YopRsaClient::post("/rest/v1.0/aggpay/pre-pay", $request);
        $data = WechatHandler::initSdk($url);
        $response->signature = $data["signature"];
        return $this->successClient($response);
    }

    //对接易宝  易宝聚合支付 异步回调
    public function yopWxCallback(Request $request) {

        $dealRecord = new DealRecord;
        Log::info('易宝微信充值-进入异步回调');
        $yopConfig = Config::get("const.yop_config");
        //易宝公钥 非商户公钥
        $yop_public_key = $yopConfig["yop_public_key"];
        //商户私钥
        $private_key = $yopConfig["private_key"];
        $result = YopSignUtils::decrypt($request['response'],$private_key, $yop_public_key);
        $data = json_decode($result,true);
        Log::info('易宝充值-异步回调解密验签成功'.$result);
        $channelOrderId = $data["channelOrderId"];//微信支付单号   商家小票校验
        $bankOrderId = $data["bankOrderId"];//商户单号   商家小票校验

        $deal_item_id = $data["orderId"];//支付交易记录唯一标识
        $dealInfo = $dealRecord->where("pay_orderid",$deal_item_id)->first();
        if(empty($dealInfo)){
            Log::info('易宝充值-该笔交易记录状态异常');
            die;
        }
        if($dealInfo->deal_type == 41){
            Log::info('微信直接支付订单-订单ID:'.$dealInfo->deal_item_id);
            $dealInfo->channel_order_id = $channelOrderId;
            $dealInfo->bank_order_id = $bankOrderId;
            $dealInfo->save();
            $order = new Order;
            $order->checkMemPay(2,$dealInfo->deal_item_id,$dealInfo->pay_orderid);
        }else{
            $userId = $dealInfo->user_id;

            $userModel = new User;
            $user = $userModel->where("id",$userId)->first();
    
            $deal = $dealRecord->investSuccess($dealInfo->id, $user->open_id, $dealInfo->amount, $channelOrderId, $bankOrderId);
        }
        
        echo "SUCCESS";
       }

    //商家小票  服务商校验 check_code
    public function checkCode(Request $request){
        $data = $request->all(); 
        $sub_mch_id = $data["sub_mch_id"];
        $out_trade_no = $data["out_trade_no"];
        $check_code = $data["check_code"];
        $url = $data["url"];

        $dealRecord = new DealRecord;
        $deal = $dealRecord->where("bank_order_id",$out_trade_no)->first();

        $channelOrderId = $deal->channel_order_id;
        $code = md5($url.'?sub_mch_id='.$sub_mch_id.'&out_trade_no='.$out_trade_no.'&transaction_id='.$channelOrderId);
        if(strncmp($check_code,$code,32) == 0){
            return $this->successClient($code);
        }
        return $this->errorClient(['info' => $check_code.'和'.$code]);
    }


    //银行卡直接支付  
    //商户需先调用该接口生成预支付订单，易宝返回支付授权token后，再使用token调起相应支付。  
    public function tradeOrder(Request $request){
        $price = $request['money'];
        if($price < 1) {
            return $this->errorClient(['info' => '充值金额不能小于1元']);
        }
        $url = $request['url'];
        $user = Auth::user()->toArray();
        $pay_config = new PayConfig;
        $payConfig = $pay_config->where("store_id",$user["store_id"])->first();

        $orderId =  "BankCard_MB_YOP_".date('Ymd').substr(time(), -4).mt_rand(1000,9999).$user["id"];

        $dealRecord = new DealRecord;
        $deal = $dealRecord->invest($user, $price*100,"银行卡快捷充值",$orderId,2);

        $yopConfig = Config::get("const.yop_config");

        $private_key = $yopConfig["private_key"];
        $appKey = $yopConfig["appKey"];
        $parentMerchantNo = $yopConfig["parentMerchantNo"];
        $merchantNo = $payConfig["yop_merchantno"];
        $notifyUrl = env("APP_URL").'/pay/yopwxcallback';
        $redirectUrl = env("APP_WEB_URL").'/gold';

        $request = new YopRequest($appKey, $private_key);

        $request->addParam("parentMerchantNo", $parentMerchantNo);//发起方商户编号
        $request->addParam("merchantNo", $merchantNo);//收款商户商编
        $request->addParam("orderId", $orderId);//商户收款请求号
        $request->addParam("orderAmount", $price);//订单金额
        $request->addParam("goodsName", '易宝充值-银行卡充值');//简单描述订单信息简单描述订单信息或商品简介，用于展示在收银台页面或者支付明细中。单笔收款必传，合单收款场景中请在子单域信息subOrderDetail里提供(*当商品名称超过85个字符时，易宝会默认保留前85个字符)        或商品简介，用于展示在收银台页面或者支付明细中
        $request->addParam("notifyUrl", $notifyUrl);//接收支付结果的通知地址,
        $request->addParam("memo", '银行卡充值');//对账备注。商户自定义参数，会展示在交易对账单中,支持85个字符（中文或者英文字母）
        $request->addParam("redirectUrl", $redirectUrl);//支付成功后跳转的URL，如商户指定页面回调地址， 支付完成后会从易宝的支付成功页跳转至商家指定页面，只有走标准收银台的订单此地址才有作用。注意：最大长度200个字符。
        
        //提交Post请求
        $response = YopRsaClient::post("/rest/v1.0/trade/order", $request);

        //取得返回结果
        $data=Self::object_array($response);
         
        $token=$data['result']['token'];
        $cashter = array(
            "appKey" => $appKey ,
            "merchantNo" => $merchantNo ,
            "token" => $token,
            "timestamp" => strtotime(date("Y-m-d H:i:s")),
            "directPayType" => '',
            "cardType" => '',
            "userNo" => $user["id"],
            "userType" => '',
            "ext" => '',
        ); 
        
        $getUrl = Self::getUrl($cashter, $private_key);   
        $getUrl=str_replace("&timestamp","&timestamp",$getUrl);
        $url = "https://cash.yeepay.com/cashier/std?" . $getUrl;

        return $this->successClient($url);
    }

    public function getUrl($response,$private_key)
    {
       $content=Self::getString($response);
       $sign=YopSignUtils::signRsa($content,$private_key);
       $url=$content."&sign=".$sign;
       return  $url;
    }

    public function object_array($array) { 
        if(is_object($array)) { 
            $array = (array)$array; 
         } if(is_array($array)) { 
             foreach($array as $key=>$value) { 
                 $array[$key] = Self::object_array($value); 
                 } 
         } 
         return $array; 
    }

    public function getString($response){

        $str="";

        foreach ($response as $key => $value) {
            $str .= $key . "=" . $value . "&";
        }
        $getSign = substr($str, 0, strlen($str) - 1);
            return $getSign;
    }
}
